package com.zbkj.service.service.merchant.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zbkj.dal.base.enums.merchant.MerOrderApptStatus;
import com.zbkj.dal.base.enums.merchant.MerOrderApptType;
import com.zbkj.dal.dao.MerchantOrderAppointmentMapper;
import com.zbkj.dal.entity.merchant.MerchantOrderAppointment;
import com.zbkj.service.model.dto.order.OrderMerAppointmentDTO;
import com.zbkj.service.service.merchant.MerchantOrderAppointmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.stream.Collectors;

@Service
public class MerchantOrderAppointmentServiceImpl extends ServiceImpl<MerchantOrderAppointmentMapper, MerchantOrderAppointment> implements MerchantOrderAppointmentService {

    @Autowired
    private MerchantOrderAppointmentMapper mapper;

    @Override
    public OrderMerAppointmentDTO createMerchantOrderAppointment(String orderNo, Integer merId, Integer uid, LocalDate apptDate, LocalTime start, LocalTime end, MerOrderApptType apptType) {
        MerchantOrderAppointment merchantOrderAppointment = new MerchantOrderAppointment();
        merchantOrderAppointment.setApptCode(IdUtil.getSnowflakeNextIdStr());
        merchantOrderAppointment.setOrderNo(orderNo);
        merchantOrderAppointment.setMerId(merId);
        merchantOrderAppointment.setUid(uid);
        merchantOrderAppointment.setApptNumber(RandomUtil.randomNumbers(4));
        merchantOrderAppointment.setApptDate(apptDate);
        merchantOrderAppointment.setApptTimeStart(start);
        merchantOrderAppointment.setApptTimeEnd(end);
        merchantOrderAppointment.setType(apptType.name());
        merchantOrderAppointment.setStatus(MerOrderApptStatus.SCHEDULED.name());
        merchantOrderAppointment.setCreateTime(LocalDateTime.now());
        merchantOrderAppointment.setUpdateTime(LocalDateTime.now());
        boolean save = super.save(merchantOrderAppointment);
        Assert.isTrue(save, "创建预约记录失败");
        OrderMerAppointmentDTO orderMerAppointmentDTO = new OrderMerAppointmentDTO();
        orderMerAppointmentDTO.setApptCode(merchantOrderAppointment.getApptCode());
        orderMerAppointmentDTO.setApptNumber(merchantOrderAppointment.getApptNumber());
        return orderMerAppointmentDTO;
    }

    @Override
    public OrderMerAppointmentDTO createMerchantOrderAppointmentWithLongTime(String orderNo, Integer merId, Integer uid, MerOrderApptType apptType) {
        return createMerchantOrderAppointment(orderNo, merId, uid, null, null, null, apptType);
    }

    @Override
    public MerchantOrderAppointment findAppointmentByOrderId(String orderId, MerOrderApptType... apptType) {
        LambdaQueryWrapper<MerchantOrderAppointment> lqw = Wrappers.lambdaQuery();
        lqw.eq(MerchantOrderAppointment::getOrderNo, orderId);
        lqw.eq(MerchantOrderAppointment::getStatus, MerOrderApptStatus.SCHEDULED.name());
        lqw.in(MerchantOrderAppointment::getType, Arrays.stream(apptType).map(MerOrderApptType::name).collect(Collectors.toSet()));
        return mapper.selectOne(lqw);
    }

    @Override
    public void cancelMerchantOrderAppointment(String orderNo, MerOrderApptType apptType) {
        LambdaUpdateWrapper<MerchantOrderAppointment> updateChainWrapper = Wrappers.lambdaUpdate();
        updateChainWrapper.set(MerchantOrderAppointment::getStatus, MerOrderApptStatus.CANCELLED.name());
        updateChainWrapper.set(MerchantOrderAppointment::getUpdateTime, LocalDateTime.now());
        updateChainWrapper.eq(MerchantOrderAppointment::getOrderNo, orderNo);
        updateChainWrapper.eq(MerchantOrderAppointment::getType, apptType.name());
        boolean update = super.update(updateChainWrapper);
        Assert.isTrue(update, "取消预约记录失败");
    }

    @Override
    public void modifyMerchantOrderAppointmentTime(String orderNo, MerOrderApptType apptType, LocalDate apptDate, LocalTime apptStart, LocalTime apptEnd) {
        LambdaUpdateWrapper<MerchantOrderAppointment> updateChainWrapper = Wrappers.lambdaUpdate();
        updateChainWrapper.set(MerchantOrderAppointment::getApptDate, apptDate);
        updateChainWrapper.set(MerchantOrderAppointment::getApptTimeStart, apptStart);
        updateChainWrapper.set(MerchantOrderAppointment::getApptTimeEnd, apptEnd);
        updateChainWrapper.set(MerchantOrderAppointment::getUpdateTime, LocalDateTime.now());
        updateChainWrapper.eq(MerchantOrderAppointment::getOrderNo, orderNo);
        updateChainWrapper.eq(MerchantOrderAppointment::getType, apptType.name());
        boolean update = super.update(updateChainWrapper);
        Assert.isTrue(update, "更新预约记录失败");
    }

}
